<template>
  <div class="app-container">
    <div class="search_container_warp">
      <el-form
        ref="queryFormRef"
        class="search_container"
        :model="queryParams"
        :inline="true"
      >
        <el-form-item prop="keywords" label="赛项名称">
          <el-input
            class="search_query"
            v-model="queryParams.matchName"
            placeholder="赛项名称"
            clearable
            @keyup.enter="queryFn"
          />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="queryFn"
            ><i-ep-search />搜索</el-button
          >
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="openDialog()"> 新增比赛</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never" class="table-container">
      <el-table
        ref="dataTableRef"
        class="customTableClass"
        v-loading="loading"
        :data="examList"
        :border="true"
        :span-method="objectSpanMethod"
      >
        <el-table-column label="序号" width="60" prop="index" align="center" />
        <!-- <el-table-column label="序号" width="60" type="index" align="center" /> -->
        <el-table-column label="赛项名称" prop="matchName" min-width="240">
          <template #default="scope">
            <span class="clickLinkClass" @click="openDialog(scope.row)">
              {{ scope.row.matchName }}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="赛项ID" align="center" prop="id" width="70" />
        <el-table-column
          label="组别"
          align="center"
          prop="matchGroupName"
          width="90"
        />
        <el-table-column
          label="开始时间"
          align="center"
          prop="startTime"
          min-width="110"
        />
        <el-table-column
          label="考试时长"
          align="center"
          prop="timeLong"
          width="85"
        />

        <el-table-column label="考试试卷" align="left" min-width="130">
          <template #default="scope">
            <el-icon
              :size="16"
              class="editIconClass"
              v-if="!scope.row.paperName"
            >
              <Edit @click="openExaminationDialog(scope.row)" />
            </el-icon>
            <span
              v-else
              class="clickLinkClass"
              @click="openExaminationDialog(scope.row)"
            >
              {{ scope.row.paperName }}
            </span>
          </template>
        </el-table-column>
        <el-table-column
          label="题数"
          align="center"
          prop="questionNumber"
          width="60"
        />
        <el-table-column label="状态" align="center" width="80">
          <template #default="scope">
            <span class="clickLinkClass" @click="handleStatus(scope.row)">
              {{ scope.row.status }}
            </span>
          </template>
        </el-table-column>

        <!-- 新增 -->
        <el-table-column
          label="备注"
          align="center"
          prop="remark"
          min-width="100"
        />

        <el-table-column label="操作" align="center" width="60">
          <template #default="scope">
            <el-icon
              :size="16"
              class="deleteIconClass"
              v-if="scope.row.status === '未发布'"
            >
              <i-ep-delete @click="handleDelete(scope.row.id)" />
            </el-icon>
          </template>
        </el-table-column>
      </el-table>

      <!-- <pagination
        v-if="total > 0"
        v-model:total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="handleQuery"
      /> -->
    </el-card>

    <!-- 新增赛项表单弹窗 -->
    <el-dialog
      v-model="dialog.visible"
      :title="dialog.title"
      width="600px"
      draggable
      align-center
      :loading="dialogLoading"
      @close="closeDialog"
    >
      <el-form
        ref="matchFormRef"
        :model="formData"
        :rules="matchRules"
        label-width="100px"
        :disabled="formDataDiabled"
      >
        <el-form-item label="赛项名称" prop="matchName">
          <el-input
            v-model="formData.matchName"
            type="textarea"
            placeholder="请输入赛项名称"
          />
        </el-form-item>

        <el-form-item label="比赛组别" prop="matchGroup">
          <el-checkbox-group v-model="formData.matchGroup">
            <el-checkbox
              v-for="item in groupOptions"
              :key="item.value"
              :value="item.value"
            >
              {{ item.label }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>

        <el-form-item label="备注" prop="remark">
          <el-input v-model="formData.remark" type="textarea" placeholder="" />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeDialog">取 消</el-button>
          <el-button type="primary" @click="handleSubmit">确 定</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 竞赛试题弹窗  -->
    <el-dialog
      v-if="examDialogVisible"
      v-model="examDialogVisible"
      modal-class="maxHeightClass"
      title="竞赛试题"
      width="600px"
      draggable
      align-center
      :loading="dialogLoading"
      @close="closeExamDialog"
    >
      <el-form
        ref="examFormRef"
        :model="examData"
        :rules="rules"
        :disabled="examDataDiabled"
      >
        <el-form-item label="赛项ID" prop="id">
          <el-input :disabled="true" v-model="examData.id" />
        </el-form-item>
        <el-form-item label="赛项名称" prop="matchName">
          <el-input :disabled="true" v-model="examData.matchName" />
        </el-form-item>
        <el-form-item label="比赛组别" prop="matchGroup">
          <el-select
            :disabled="true"
            v-model="examData.matchGroup"
            @change="matchGroupChange"
          >
            <el-option
              v-for="item in groupOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="比赛试题" prop="paperId">
          <el-select :disabled="statusDisabled" v-model="examData.paperId">
            <el-option
              v-for="item in paperIdOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="比赛时间" prop="startTime">
          <el-date-picker
            :disabled="statusDisabled"
            v-model="examData.startTime"
            type="datetime"
            placeholder="请选择比赛时间"
            format="YYYY-MM-DD HH:mm"
            value-format="YYYY-MM-DD HH:mm"
            :disabled-date="disabledDate"
            time-format="HH:mm"
          />
        </el-form-item>
        <el-form-item label="比赛时长(分钟)" prop="timeLong">
          <el-input
            :disabled="statusDisabled"
            v-model="examData.timeLong"
            type="number"
            placeholder="请输入比赛时长"
            min="1"
            @change="changeFn"
          />
        </el-form-item>
        <el-form-item label="状态" prop="statusCode">
          <el-select v-model="examData.statusCode">
            <el-option
              v-for="item in statusOptionsList"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            :disabled="statusDisabled"
            v-model="examData.remark"
            type="textarea"
          />
        </el-form-item>
      </el-form>

      <template #footer>
        <div class="dialog-footer">
          <el-button @click="closeExamDialog">取 消</el-button>
          <el-button
            type="primary"
            @click="handleExamSubmit"
            :disabled="examDataDiabled"
            >确 定</el-button
          >
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import {
  getEventList,
  matchCreate,
  matchUpdate,
  matchDelete,
  getPaperOptions,
  setPaper,
  updateStatus,
  getDictionaryPage,
} from "@/api/examManagement";
import { Options } from "@/api/examPaperManagement/types";
import { examItemVO, examItemForm } from "@/api/examManagement/types";
import { queryFilter, computeHeiht, mergeCalculation } from "@/utils/index";

defineOptions({
  name: "EventManagement",
  inheritAttrs: false,
});

const queryFormRef = ref(ElForm);
const matchFormRef = ref(ElForm);
const examFormRef = ref(ElForm);
const loading = ref(false);
const dialogLoading = ref(false);

const examList = ref<examItemVO[]>([]);
const originaldataList = ref<examItemVO[]>([]);

const dialog = reactive({
  title: "",
  visible: false,
});

// 查询条件
const queryParams = reactive<examItemVO>({});
// 赛项对象
const formData = reactive<any>({
  matchName: "",
  matchGroup: [],
  remark: "",
});

const groupOptions = ref<Options[]>([]);
const statusOptions = ref<Options[]>([]);
const statusOptions2 = ref<Options[]>([]);
// 状态
statusOptions.value = [
  {
    label: "未发布",
    value: 1,
  },
  {
    label: "已发布",
    value: 2,
  },
];
// 状态
statusOptions2.value = [
  {
    label: "未发布",
    value: 1,
  },
  {
    label: "已发布",
    value: 2,
  },
  {
    label: "已结束",
    value: 3,
  },
];
const statusOptionsList = computed(() => {
  return statusDisabled.value || examDataDiabled
    ? statusOptions2.value
    : statusOptions.value;
});

const paperIdOptions = ref<Options[]>([]);

const disabledDate = (time: Date) => {
  return time.getTime() < Date.now() - 8.64e7; // 8.64e7 毫秒数代表一天
};

const formDataDiabled = computed(() => {
  let flag: boolean = false;
  examList.value.forEach((item) => {
    if (item.matchCode === formData.matchCode && item.status !== "未发布") {
      flag = true;
    }
  });
  return !!(formData.id && flag);
});
const examDataDiabled = computed(() => examData.status === "已结束");

const matchRules = reactive({
  matchName: [
    {
      required: true,
      message: "",
      trigger: "blur",
    },
  ],
  matchGroup: [{ required: true, message: "", trigger: "change" }],
});

const rules = reactive({
  paperId: [
    {
      required: true,
      message: " ",
      trigger: "change",
    },
  ],
  startTime: [{ required: true, message: " ", trigger: "change" }],
  timeLong: [{ required: true, message: " ", trigger: "change" }],
  statusCode: [{ required: true, message: " ", trigger: "change" }],
});

const examDialogVisible = ref(false);
const statusDisabled = ref(false);

interface Checked {
  id?: number;
  name?: string;
}

let checked: Checked = reactive({});
let examData: examItemForm = reactive({});

/** 查询 */
function queryFn() {
  let { matchName } = queryParams;
  let arr: Options[] = [{ label: "matchName", value: matchName || "" }];
  if (matchName) {
    examList.value = queryFilter(originaldataList.value, arr);
  } else {
    handleQuery();
  }
}

/** 查询 */
function handleQuery() {
  queryParams.matchName = "";
  loading.value = true;
  getEventList()
    .then(({ data }) => {
      let codeList = new Map();
      let indexList = new Map();
      let listData = data.map((item: any, index: number) => {
        // 把赛项下的组别收集起来
        if (!codeList.has(item.matchCode)) {
          codeList.set(item.matchCode, [item.matchGroup]);
          indexList.set(item.matchCode, indexList.size + 1);
        } else {
          let list = codeList.get(item.matchCode);
          list.splice(list.length, 0, item.matchGroup);

          codeList.set(item.matchCode, list);
        }
        // status转name
        statusOptions2.value?.forEach((v: any) => {
          if (v.label === item.status) {
            item.statusCode = v.value;
          }
        });
        // 组别转name
        groupOptions.value?.forEach((v: any) => {
          if (v.value === item.matchGroup) {
            item.matchGroupName = v.label;
          }
        });
        return item;
      });
      let num = 0;
      // 把赛项下的组别赋值
      listData.forEach((item: any) => {
        item.startTime = item.startTime ? item.startTime.slice(0, 16) : "";
        if (codeList.has(item.matchCode)) {
          item.matchGroupList = codeList.get(item.matchCode);
          item.index = indexList.get(item.matchCode);
        }
      });

      examList.value = [...listData];
      originaldataList.value = [...listData];
    })
    .finally(() => {
      loading.value = false;
    });
}
/** 重置查询 */
function resetQuery() {
  queryFormRef.value.resetFields();
  // queryParams.pageNum = 1;
  handleQuery();
}

function changeFn(data: any) {
  examData.timeLong = data.replace(/\D/g, "");
  let long = Number(examData.timeLong);
  if (!long) {
    examData.timeLong = undefined;
  }
}

function openDialog(data?: examItemVO) {
  let title: string = "新增赛项";
  if (data?.id) {
    title = "修改赛项";
    formData.id = data.id;
    formData.status = data.statusCode;
    formData.matchCode = data.matchCode;
    formData.matchName = data.matchName;
    formData.remark = data.remark;
    formData.matchGroup = data.matchGroupList;
    // Object.assign(formData, data);
  } else {
    formData.status = "";
    formData.matchCode = "";
    formData.matchName = "";
    formData.remark = "";
    formData.matchGroup = [];
  }
  dialog.title = title;
  dialog.visible = true;
}

/** 新增和修改赛项 */
function handleSubmit() {
  matchFormRef.value.validate((valid: boolean) => {
    if (valid) {
      let params: any = {
        matchName: formData.matchName,
        matchGroup: formData.matchGroup,
        remark: formData.remark,
      };
      dialogLoading.value = true;
      if (formData.id) {
        params.matchCode = formData.matchCode;
        matchUpdate(params)
          .then((res) => {
            ElMessage.success("修改成功");
            dialog.visible = false;
            handleQuery();
          })
          .finally(() => {
            dialogLoading.value = false;
          });
      } else {
        matchCreate(params)
          .then((res) => {
            ElMessage.success("新增成功");
            dialog.visible = false;
            handleQuery();
          })
          .finally(() => {
            dialogLoading.value = false;
          });
      }
    }
  });
}

/** 关闭表单弹窗 */
function closeDialog() {
  dialog.visible = false;
  resetForm();
}

/** 重置表单 */
function resetForm() {
  formData.id = null;
  matchFormRef.value.resetFields();
  matchFormRef.value.clearValidate();
}

/** 删除 */
function handleDelete(id: number) {
  ElMessageBox.confirm("确认删除数据项?", "确认删除", {
    confirmButtonText: "确 定",
    cancelButtonText: "取 消",
    type: "error",
  }).then(() => {
    loading.value = true;
    matchDelete(id)
      .then(() => {
        ElMessage.success("删除成功");
        resetQuery();
      })
      .finally(() => (loading.value = false));
  });
}
/** 打开配置弹框 */
function openExaminationDialog(row: examItemVO) {
  if (!row.matchGroup) {
    return;
  }
  getPaperOptionsFn(row.matchGroup);

  examDialogVisible.value = true;
  Object.assign(examData, row);
}

/** 切换比赛组别 */
function matchGroupChange(value: number) {
  getPaperOptionsFn(value);
}

/** 查询赛项的试卷选项 */
function getPaperOptionsFn(matchGroup: number) {
  getPaperOptions(matchGroup)
    .then(({ data }) => {
      paperIdOptions.value = data.map((v: any) => {
        return {
          value: v.id,
          label: v.name,
        };
      });
    })
    .finally(() => (loading.value = false));
}

/** 关闭表单弹窗 */
function closeExamDialog() {
  examDialogVisible.value = false;
  statusDisabled.value = false;
  examResetForm();
}
/** 重置表单 */
function examResetForm() {
  examFormRef.value.resetFields();
  examFormRef.value.clearValidate();
  examData.id = undefined;
}

function handleStatus(row: examItemVO) {
  examDialogVisible.value = true;
  statusDisabled.value = true;
  Object.assign(examData, row);
}

/** 保存提交 */
function handleExamSubmit() {
  examFormRef.value.validate((valid: boolean) => {
    if (valid) {
      dialogLoading.value = true;
      if (statusDisabled.value) {
        updateStatus({
          id: examData.id,
          status: examData.statusCode,
          remark: examData.remark,
        })
          .then(() => {
            ElMessage.success("配置成功");
            closeExamDialog();
            resetQuery();
          })
          .finally(() => (dialogLoading.value = false));
        return;
      }
      let params: any = {
        id: examData.id,
        paperId: examData.paperId,
        startTime: examData.startTime + ":00",
        timeLong: examData.timeLong,
        status: examData.statusCode,
        remark: examData.remark,
      };
      setPaper(params)
        .then(() => {
          ElMessage.success("配置成功");
          closeExamDialog();
          resetQuery();
        })
        .finally(() => (dialogLoading.value = false));
    }
  });
}

async function getCommonParameters() {
  let { data } = await getDictionaryPage("MATCH_GROUP", 1);
  groupOptions.value = data.map((v: any) => {
    return {
      label: v.name,
      value: v.myKey - 0,
    };
  });

  handleQuery();
}

interface SpanMethodProps {
  row: any;
  rowIndex: number;
  columnIndex: number;
}
/**
 * @param row 当前行
 * @param column 当前列
 * @param rowIndex 当前行号，第几行
 * @param columnIndex 当前列号
 * @returns {{rowspan: number, colspan: number}}
 */
const objectSpanMethod = ({ row, rowIndex, columnIndex }: SpanMethodProps) => {
  if (columnIndex === 0) {
    let data: any = [...examList.value];
    const { intRowSpan } = mergeCalculation(data, rowIndex, "index");
    return {
      // 当渲染执行到某一行的首列时，或者执行到首列时，对其中的行进行渲染时，例如渲染到第四行时，发现rowspan为3时，
      // 那就是首列中从第四行开始合并，合并3行，四、五、六这三行合并为一行。
      rowspan: intRowSpan,
      colspan: intRowSpan == 0 ? 0 : 1, // 如果不合并行，就返回0，说白了就不合并
    };
  } else if (columnIndex === 1) {
    let data: any = [...examList.value];
    const { intRowSpan } = mergeCalculation(data, rowIndex, "matchName");
    return {
      // 当渲染执行到某一行的首列时，或者执行到首列时，对其中的行进行渲染时，例如渲染到第四行时，发现rowspan为3时，
      // 那就是首列中从第四行开始合并，合并3行，四、五、六这三行合并为一行。
      rowspan: intRowSpan,
      colspan: intRowSpan == 0 ? 0 : 1, // 如果不合并行，就返回0，说白了就不合并
    };
  }
};

onMounted(() => {
  getCommonParameters();
  computeHeiht();
});
</script>
<style scoped lang="scss"></style>
